home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / N-P / NIFTY / myCShell / scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-17  |  17.8 KB  |  775 lines  |  [TEXT/KAHL]

  1. /*********************************************************
  2.  "scroll.c"
  3.  
  4.  by John A. Love, III [ Washington Apple Pi Users' Group]
  5.  
  6.  using Symantec's "THINK C", v 5.00
  7.  *********************************************************/
  8.  
  9.  
  10.  
  11. #include "protos"
  12.  
  13. #include "globals.h"
  14. #include "extern.h"
  15.  
  16.  
  17.  
  18.  
  19. /* +++++++++++++++++++++
  20. ** Our local prototypes:
  21. ** +++++++++++++++++++++ */
  22.  
  23. pascal void    UpActionProc (ControlHandle ctl, short part);
  24. pascal void    DownActionProc (ControlHandle ctl, short part);
  25. void        ScrollToThumbPosition (ControlHandle ctl);
  26. void        DoPageUp (ControlHandle ctl);
  27. void        DoPageDown (ControlHandle ctl);
  28. void        ScrollContents (ControlHandle ctl, short dh, short dv);
  29. void        SetMaxCtlValue (ControlHandle ctl, short excess);
  30. void        SetCtlValueToMin (ControlHandle ctl);
  31.  
  32.  
  33.  
  34.     /* +++++++++++++++++++++++++++++++++++++++
  35.     ** Our Globals for the scrolling routines:
  36.     ** +++++++++++++++++++++++++++++++++++++++ */
  37.  
  38.     #define            kFlashDelay    8
  39.  
  40.     WindowPtr        window;
  41.     long            VertOrHoriz;
  42.     short            oldCtlValue;
  43.     ControlHandle    ourControl;
  44.     Rect            windContentsRect, fullContentsRect, updateRect;
  45.     long            finalTicks;
  46.     
  47.     
  48.  
  49.  
  50. short GetControlType (ControlHandle ctl)    {
  51.  
  52.         short        RomMapInsertLoc    = 0x0B9E;
  53.      /* short        mapTrue            = -1; */
  54.  
  55.         short        varCode, CDEFRsrcID, cType;
  56.         Handle        CDEFHandle;
  57.         ResType        CDEFType;
  58.         Str255        CDEFName;
  59.  
  60.  
  61.     varCode = GetCVariant(ctl);
  62.  
  63.     CDEFHandle = (*ctl)->contrlDefProc;
  64.     CDEFHandle = (Handle)QuickStrip((longPtr)CDEFHandle);
  65.     ;
  66.     LoadResource(CDEFHandle);                /* May have been purged ... */
  67.     *((wordPtr)RomMapInsertLoc) = mapTrue;    /* Thanks, Ben Cranston !! */
  68.     GetResInfo(CDEFHandle, &CDEFRsrcID, &CDEFType, CDEFName);
  69.  
  70.     cType = 16 * CDEFRsrcID + varCode;
  71.     return (cType);
  72.  
  73. }    /* GetControlType */
  74.  
  75.  
  76.  
  77. ControlHandle    GetDefaultButton (DialogPtr dlg)    {
  78.  
  79.         short            bType;
  80.         Handle            bHandle;
  81.         Rect            bRect;
  82.         
  83.     
  84.     if (dlg == nil)        return (nil);
  85.     ;
  86.     GetDItem(dlg, ((DialogPeek)dlg)->aDefItem, &bType, &bHandle, &bRect);    
  87.     if (bType == ctrlItem + btnCtrl)    return ( (ControlHandle)bHandle );
  88.     else                                return (nil);
  89.     
  90. }    /* GetDefaultButton */
  91.  
  92.  
  93.  
  94. void    FrameDefaultButton (DialogPtr dlg)    {
  95. /* See "THINKin' CaP", Winter 1991 */
  96.  
  97.         ControlHandle    okButton;
  98.         Rect            bRect;
  99.         short            bHeight, roundCorner;
  100.         PenState        pnState;
  101.         RGBColor        foreColor;
  102.         AuxCtlHandle    acHndl;
  103.         CCTabHandle        ccTable;
  104.         
  105.         
  106.     okButton = GetDefaultButton(dlg);
  107.     if (okButton == nil)    return;
  108.     
  109.     GetPenState(&pnState);
  110.     ;
  111.     PenNormal();
  112.     PenSize(3, 3);
  113.  
  114.     bRect = (*okButton)->contrlRect;
  115.     bHeight = bRect.bottom - bRect.top;
  116.     
  117.     InsetRect(&bRect, -4, -4);
  118.     roundCorner = (bHeight + 1) / 2;
  119.     if ( !isActive((*okButton)->contrlOwner) )    PenPat(&gray);
  120.     
  121.     if (gMac2)        {
  122.         GetForeColor(&foreColor);
  123.         if (GetAuxCtl(okButton, &acHndl))        {
  124.             ccTable = (**acHndl).acCTable;
  125.             RGBForeColor(& ((**ccTable).ctTable)[cFrameColor].rgb );
  126.         }
  127.     }    /* gMac2 */
  128.     ;
  129.     FrameRoundRect(&bRect, roundCorner, roundCorner);
  130.     ;
  131.     if (gMac2)    RGBForeColor(&foreColor);
  132.     
  133.  // ValidRect(&bRect);  --  causes problems with updates.
  134.     ;
  135.     SetPenState(&pnState);
  136.  
  137. }    /* FrameDefaultButton */
  138.  
  139.  
  140.  
  141. void    SimulateClick (ControlHandle ctl)    {
  142.  
  143.         
  144.     HiliteControl(ctl, inButton);
  145.     Delay(kFlashDelay, &finalTicks);
  146.     HiliteControl(ctl, drawCntl);
  147.  
  148. }    /* SimulateClick */
  149.  
  150.  
  151.  
  152. /* -----------------------------------------------------
  153. ** Mouse clicked on the line arrows
  154. **
  155. ** NOTE As a matter of academic principle, avoid speed
  156. ** penalities associated with TRAP overhead if possible.
  157. ** ----------------------------------------------------- */
  158.  
  159. pascal void    UpActionProc (ControlHandle ctl, short part)    {
  160.  
  161.         short    newCtlValue;            /* # of lines */
  162.         short    dv, dh, difference;        /* # of pixels */
  163.         Rect    temp;
  164.  
  165.  
  166.     if (part == 0)    return;                /* Mouse moved OUTSIDE the Control !! */
  167.  
  168.     oldCtlValue = (**ctl).contrlValue;
  169.     dv = 12;                            /* Vertical, NOT sideways !! */
  170.     dh = 0;
  171.  
  172.     difference = (oldCtlValue - (**ctl).contrlMin) * 12;
  173.     if (difference == 0)    return;        /* Prevent flickering. */
  174.     if (difference < dv)    dv = difference;
  175.  
  176.     newCtlValue = oldCtlValue - 1;        /* Decrement one line's worth. */
  177.     temp = (**ctl).contrlRect;            // Just because _SetCtlValue is buggy for
  178.     InsetRect(&temp, 1, 1);                // a Mac II set to black-and-white.
  179.     ClipRect(&temp);                    // Mac II in color works okay, though ?????
  180.     SetCtlValue(ctl, newCtlValue);
  181.     ClipRect(&window->portRect);        /* Reset. */
  182.  
  183.     if (VertOrHoriz == horizScrollID)
  184.     {
  185.         dh = dv;                        /* Sideways, NOT vertical !! */
  186.         dv = 0;
  187.     }    /* in horizontal scroll bar */
  188.  
  189.     ScrollContents(ctl, dh, dv);        // Contents scroll DOWN, or RIGHT.
  190.  
  191.     Delay(kFlashDelay, &finalTicks);    /* ... otherwise too fast. */
  192.  
  193. }    /* UpActionProc */
  194.  
  195.  
  196.  
  197. pascal void    DownActionProc (ControlHandle ctl, short part)    {
  198.  
  199.         short    newCtlValue;            /* # of lines */
  200.         short    dv, dh, difference;        /* # of pixels */
  201.         Rect    temp;
  202.  
  203.  
  204.     if (part == 0)    return;                /* Mouse moved OUTSIDE the Control !! */
  205.  
  206.     oldCtlValue = (**ctl).contrlValue;
  207.     dv = 12;                            /* Vertical, NOT sideways !! */
  208.     dh = 0;
  209.  
  210.     difference = ((**ctl).contrlMax - oldCtlValue) * 12;
  211.     if (difference == 0)    return;        /* Prevent flickering. */
  212.     if (difference < dv)    dv = difference;
  213.  
  214.     newCtlValue = oldCtlValue + 1;        /* Bump it one line's worth. */
  215.     temp = (**ctl).contrlRect;
  216.     InsetRect(&temp, 1, 1);
  217.     ClipRect(&temp);
  218.     SetCtlValue(ctl, newCtlValue);
  219.     ClipRect(&window->portRect);        /* Reset. */
  220.  
  221.     if (VertOrHoriz == horizScrollID)
  222.     {
  223.         dh = dv;                        /* Sideways, NOT vertical !! */
  224.         dv = 0;
  225.     }    /* in horizontal scroll bar */
  226.  
  227.     ScrollContents(ctl, -dh, -dv);        // Contents scroll UP, or LEFT.
  228.  
  229.     Delay(kFlashDelay, &finalTicks);    /* ... otherwise too fast. */
  230.  
  231. }    /* DownActionProc */
  232.  
  233.  
  234.  
  235. /* -----------------------------------------------------------------
  236. ** Scroll contents of window to match the pre-set Scroll Bar setting
  237. ** ----------------------------------------------------------------- */
  238.  
  239. void    ScrollToThumbPosition (ControlHandle ctl)    {
  240.  
  241.         short    newCtlValue, dh, dv;
  242.  
  243.  
  244.     dh = 0;
  245.     dv = 0;
  246.     newCtlValue = (**ctl).contrlValue;
  247.  
  248.     if (VertOrHoriz == horizScrollID)
  249.         dh = -(newCtlValue - oldCtlValue) * 12;    /* Normally, teLineHite */
  250.     else /* = vertScrollID */ dv = -(newCtlValue - oldCtlValue) * 12;
  251.  
  252.     ScrollContents(ctl, dh, dv);
  253.  
  254.     Delay(8, &finalTicks);
  255.  
  256. }    /* ScrollToThumbPosition */
  257.  
  258.  
  259.  
  260. /* ----------------------------------------------
  261. ** Thumb goes UP; text, PICTure etc. scrolls DOWN
  262. ** ---------------------------------------------- */
  263.  
  264. void    DoPageUp (ControlHandle ctl)    {
  265.  
  266.         short    partControl, newCtlValue, dv, ctlDelta;
  267.         Point    newPoint;
  268.         Rect    temp;
  269.         
  270.  
  271.     if (VertOrHoriz == horizScrollID)
  272.         /* = (right+1-left) - scrollWidth: */
  273.         dv = window->portRect.right - window->portRect.left - growBoxSize;
  274.     else            /* VertOrHoriz = vertScrollID */
  275.         /* = (bottom+1-top) - scrollHeight: */
  276.         dv = window->portRect.bottom - window->portRect.top - growBoxSize;
  277.     ctlDelta = dv;
  278.     /* Normally divide by teLineHite, a field of the TERecord whose Handle */
  279.     /* is usually stored in the wRefCon field of the WindowRecord           */
  280.     ctlDelta = (ctlDelta / 12) - 1;                /* Leave 1 line's-worth showing. */
  281.  
  282.     while (StillDown())    {
  283.  
  284.         GetMouse(&newPoint);
  285.         partControl = TestControl(ctl, newPoint);
  286.         if (partControl == inPageUp)    {            /* Still INSIDE Control ... */
  287.  
  288.             oldCtlValue = (**ctl).contrlValue;
  289.             newCtlValue = oldCtlValue - ctlDelta;
  290.             temp = (**ctl).contrlRect;
  291.             InsetRect(&temp, 1, 1);
  292.             ClipRect(&temp);
  293.             SetCtlValue(ctl, newCtlValue);            /* Compensates if newCtlValue */
  294.             ClipRect(&window->portRect);            /* overshoots ctlMin.         */
  295.             ScrollToThumbPosition(ctl);
  296.  
  297.         }    /* if partControl = inPageUp */
  298.  
  299.     }    /* while StillDown */
  300.  
  301. }    /* DoPageUp */
  302.  
  303.  
  304.  
  305. /* ----------------------------------------------
  306. ** Thumb goes DOWN; text, PICTure etc. scrolls UP
  307. ** ---------------------------------------------- */
  308.  
  309. void    DoPageDown (ControlHandle ctl)    {
  310.  
  311.         short    partControl, newCtlValue, dv, ctlDelta;
  312.         Point    newPoint;
  313.         Rect    temp;
  314.  
  315.  
  316.     if (VertOrHoriz == horizScrollID)
  317.         /* = (right+1-left) - scrollWidth: */
  318.         dv = window->portRect.right - window->portRect.left - growBoxSize;
  319.     else            /* VertOrHoriz = vertScrollID */
  320.         /* = (bottom+1-top) - scrollHeight: */
  321.         dv = window->portRect.bottom - window->portRect.top - growBoxSize;
  322.  
  323.     ctlDelta = (dv / 12) - 1;
  324.  
  325.     while (StillDown())    {
  326.  
  327.         GetMouse(&newPoint);
  328.         partControl = TestControl(ctl, newPoint);
  329.         if (partControl == inPageDown)    {            /* Still INSIDE Control ... */
  330.  
  331.             oldCtlValue = (**ctl).contrlValue;
  332.             newCtlValue = oldCtlValue + ctlDelta;
  333.             temp = (**ctl).contrlRect;
  334.             InsetRect(&temp, 1, 1);
  335.             ClipRect(&temp);
  336.             SetCtlValue(ctl, newCtlValue);            /* Compensates if newCtlValue */
  337.             ClipRect(&window->portRect);            /* overshoots ctlMax.         */
  338.             ScrollToThumbPosition(ctl);
  339.  
  340.         }    /* if partControl = inPageDown */
  341.  
  342.     }    /* while StillDown */
  343.  
  344. }    /* DoPageDown */
  345.  
  346.  
  347.  
  348. void    ScrollContents(ControlHandle ctl, short dh, short dv)    {
  349.  
  350.  
  351.  
  352. }    /* ScrollContents */
  353.  
  354.  
  355.  
  356. /* --------------------------
  357. ** Our main Scrolling routine
  358. ** -------------------------- */
  359.  
  360. void    Scroll (ControlHandle ctl, short part, Point Pt)    {
  361.  
  362.  
  363.     window = (**ctl).contrlOwner;
  364.     SetPort(window);
  365.     VertOrHoriz = (**ctl).contrlRfCon;                /* Up/Down or sideways ?? */
  366.     oldCtlValue = GetCtlValue(ctl);
  367.  
  368.     switch (part)    {
  369.  
  370.         case inUpButton:
  371.             /* Throw away the result: */
  372.             TrackControl(ctl, Pt, (ProcPtr)&UpActionProc);
  373.             break;
  374.  
  375.         case inDownButton:
  376.             TrackControl(ctl, Pt, (ProcPtr)&DownActionProc);
  377.             break;
  378.  
  379.         case inPageUp:
  380.             DoPageUp(ctl);
  381.             break;
  382.  
  383.         case inPageDown:
  384.             DoPageDown(ctl);
  385.             break;
  386.  
  387.         case inThumb:
  388.         {
  389.                 Rect    temp;
  390.  
  391.             temp = (**ctl).contrlRect;
  392.             InsetRect(&temp, 1, 1);
  393.             ClipRect(&temp);
  394.             if (TrackControl(ctl, Pt, nil) != 0)
  395.                 ScrollToThumbPosition(ctl);
  396.             ClipRect(&window->portRect);        /* Reset. */
  397.             break;
  398.         }
  399.  
  400.         default:    break;
  401.  
  402.     }    /* switch */
  403.  
  404. }    /* Scroll */
  405.  
  406.  
  407.  
  408. /* -------------------------------------------------------
  409. ** Set ONLY the maximum value(s) because the attached CNTL
  410. ** resources(s) specify the minimum -- generally zero.
  411. ** ------------------------------------------------------- */
  412.  
  413. void    SetMaxCtlValue (ControlHandle ctl, short excess)    {
  414.  
  415.         short    maxValue;
  416.         Rect    temp;
  417.  
  418.  
  419.     if (excess <= 0)
  420.         maxValue = (**ctl).contrlMin;        /* Inactivates Control since max = min. */
  421.     else    // Contents taller than window->
  422.         maxValue = (excess + 11) / 12;        /* ... by this much [rounded up].       */
  423.  
  424.     if (maxValue != (**ctl).contrlMax)
  425.     {
  426.         temp = (**ctl).contrlRect;
  427.         InsetRect(&temp, 1, 1);
  428.         ClipRect(&temp);
  429.         SetCtlMax(ctl, maxValue);
  430.     }
  431.  
  432. }    /* SetMaxCtlValue */
  433.  
  434.  
  435.  
  436. void    SetMaxCtls (WindowPtr windPtr)    {
  437.  
  438.         RgnHandle        oldClip;
  439.         ControlHandle    ctlHndl;
  440.         short            dest, view;
  441.  
  442.  
  443.     oldClip = NewRgn();
  444.     GetClip(oldClip);
  445.  
  446.     ctlHndl = ScrollVert(windPtr);
  447.     if (ctlHndl != nil)
  448.     {
  449.         view = windContentsRect.bottom - windContentsRect.top;
  450.         dest = fullContentsRect.bottom - fullContentsRect.top;
  451.         SetMaxCtlValue(ctlHndl, dest - view);
  452.     }   /* if ctlHndl != nil */
  453.  
  454.     /* ----- */
  455.  
  456.     ctlHndl = ScrollHoriz(windPtr);
  457.     if (ctlHndl != nil)
  458.     {
  459.         view = windContentsRect.right - windContentsRect.left;
  460.         dest = fullContentsRect.right - fullContentsRect.left;
  461.         SetMaxCtlValue(ctlHndl, dest - view);
  462.     }    /* if ctlHndl != nil */
  463.  
  464.     SetClip(oldClip);
  465.     DisposeRgn(oldClip);
  466.  
  467. }    /* SetMaxCtls */
  468.  
  469.  
  470.  
  471. /* --------------------------------
  472. ** Called by the "HandleMouse" PROC
  473. ** -------------------------------- */
  474.  
  475. void    SetCtlValueToMin (ControlHandle ctl)    {
  476.  
  477.         Rect    temp;
  478.  
  479.  
  480.     if (ctl == nil)    return;
  481.  
  482.     temp = (**ctl).contrlRect;
  483.     InsetRect(&temp, 1, 1);                /* See comments in "UpActionProc". */
  484.     ClipRect(&temp);
  485.     SetCtlValue(ctl, GetCtlMin(ctl));
  486.  
  487. }    /* SetCtlValueToMin */
  488.  
  489.  
  490.  
  491. void    SetCtlsToMin (WindowPtr windPtr)    {
  492.  
  493.         RgnHandle    oldClip;
  494.  
  495.  
  496.     oldClip = NewRgn();
  497.     GetClip(oldClip);
  498.  
  499.     SetCtlValueToMin(ScrollHoriz(windPtr));
  500.     SetCtlValueToMin(ScrollVert(windPtr));
  501.  
  502.     SetClip(oldClip);
  503.     DisposeRgn(oldClip);
  504.  
  505. }    /* SetCtlsToMin */
  506.  
  507.  
  508.  
  509. /* --------------------------
  510. ** Does she or doesn't she ??
  511. ** -------------------------- */
  512.  
  513. Boolean    DrawMyControl (ControlHandle ctl)    {
  514.  
  515.     if ( (ctl != nil) && ((**ctl).contrlMax > (**ctl).contrlMin) )    return (true);
  516.     else                                                            return (false);
  517.  
  518. }    /* DrawMyControl */
  519.  
  520.  
  521.  
  522. /* --------------------------------
  523.    Retrieve Control Handle, if any:
  524.    -------------------------------- */
  525.  
  526. ControlHandle    ScrollHoriz (WindowPtr wp)    {
  527.  
  528.     ourControl = ((WindowPeek)wp)->controlList;
  529.  
  530.     while (ourControl)    {
  531.         if ((*ourControl)->contrlRfCon == horizScrollID) break;
  532.         ourControl = (*ourControl)->nextControl;
  533.     }    /* while */
  534.  
  535.     return(ourControl);
  536.  
  537. }    /* ScrollHoriz */
  538.  
  539.  
  540.  
  541. ControlHandle    ScrollVert (WindowPtr wp)    {
  542.  
  543.     ourControl = ((WindowPeek)wp)->controlList;
  544.  
  545.     while (ourControl)    {
  546.         if ((*ourControl)->contrlRfCon == vertScrollID) break;
  547.         ourControl = (*ourControl)->nextControl;
  548.     }    /* while */
  549.  
  550.     return(ourControl);
  551.  
  552. }    /* ScrollVert */
  553.  
  554.  
  555.  
  556. /* ------------------
  557.    Hello, or GoodBye:
  558.    ------------------ */
  559.  
  560. void    ScrollShow (WindowPtr wp)    {
  561.  
  562.     ourControl = ScrollVert(wp);
  563.     ;
  564.     if (ourControl) ShowControl(ourControl);
  565.     /* ----- */
  566.     ourControl = ScrollHoriz(wp);
  567.     ;
  568.     if (ourControl) ShowControl(ourControl);
  569.  
  570. }   /* ScrollShow */
  571.  
  572.  
  573.  
  574. void    ScrollHide (WindowPtr wp)    {
  575.  
  576.     ourControl = ScrollVert(wp);
  577.     ;
  578.     if (ourControl) HideControl(ourControl);
  579.     /* ----- */
  580.     ourControl = ScrollHoriz(wp);
  581.     ;
  582.     if (ourControl) HideControl(ourControl);
  583.  
  584. }   /* ScrollHide */
  585.  
  586.  
  587.  
  588. /* -----------------------------------------------------------------
  589.    Explicitly include the Scroll Bars in the window's Update region.
  590.    This Update region will purposely overlap the Grow Box.
  591.    ----------------------------------------------------------------- */
  592.  
  593. void    InvalidScroll (WindowPtr wp)    {
  594.  
  595.     if (ScrollVert(wp))
  596.     {
  597.         updateRect = wp->portRect;
  598.         updateRect.left = updateRect.right + frame - scrollWidth;
  599.         InvalRect(&updateRect);
  600.     }    /* if a vertical Scroll Bar */
  601.  
  602.     if (ScrollHoriz(wp))
  603.     {
  604.         updateRect = wp->portRect;
  605.         updateRect.top = updateRect.bottom + frame - scrollHeight;
  606.         InvalRect(&updateRect);
  607.     }    /* if */
  608.  
  609. }   /* InvalidScroll */
  610.  
  611.  
  612.  
  613. void    ValidScroll (WindowPtr wp)    {
  614.  
  615.     if (ScrollVert(wp))
  616.     {
  617.         updateRect = wp->portRect;
  618.         updateRect.left = updateRect.right + frame - scrollWidth;
  619.         ValidRect(&updateRect);
  620.     }    /* if a vertical Scroll Bar */
  621.  
  622.     if (ScrollHoriz(wp))
  623.     {
  624.         updateRect = wp->portRect;
  625.         updateRect.top = updateRect.bottom + frame - scrollHeight;
  626.         ValidRect(&updateRect);
  627.     }    /* if */
  628.  
  629. }   /* ValidScroll */
  630.  
  631.  
  632.  
  633. void    ScrollResize (WindowPtr wp)    {
  634. /* Remember, the portRect does NOT include the window frame,
  635.    whereas the Scroll Bar and Grow Box sizes do:             */
  636.  
  637.         Rect    contentRect;
  638.         short    ctlWidth, ctlHeight;
  639.         short    ctlTop, ctlLeft, ctlBottom, ctlRight;
  640.  
  641.  
  642.     contentRect = wp->portRect;
  643.  
  644.   /* Need to clip to new portRect for growing or zooming because window
  645.      is still clipped to OLD portRect.  Otherwise, upon enlarging the
  646.      window, the ScrollShow PROC would NOT display the Scroll Bars:     */
  647.  
  648.     ClipRect(&contentRect);
  649.  
  650.     ScrollHide(wp);                    /* Hide-and-Go Seek !! */
  651.  
  652.     ourControl = ScrollVert(wp);
  653.     if (ourControl)
  654.     {
  655.         ctlTop = contentRect.top - frame;
  656.         ctlLeft = (contentRect.right + frame) - scrollWidth;
  657.         ctlBottom = (contentRect.bottom + frame) - growBoxSize;
  658.         ctlHeight = ctlBottom - ctlTop;
  659.         ;
  660.         SizeControl(ourControl, scrollWidth, ctlHeight);
  661.         MoveControl(ourControl, ctlLeft, ctlTop);
  662.     }   /* Vertical ScrollBar */
  663.   /* ----- */
  664.     ourControl = ScrollHoriz(wp);
  665.     if (ourControl)
  666.     {
  667.         ctlTop = (contentRect.bottom + frame) - scrollHeight;
  668.         ctlLeft = contentRect.left - frame;
  669.         ctlRight = (contentRect.right + frame) - growBoxSize;
  670.         ctlWidth = ctlRight - ctlLeft;
  671.         ;
  672.         SizeControl(ourControl, ctlWidth, scrollHeight);
  673.         MoveControl(ourControl, ctlLeft, ctlTop);
  674.     }   /* Horizontal ScrollBar */
  675.  
  676.     ScrollShow(wp);                    /* Peek-a-Boo !! */
  677.  
  678. }   /* ScrollResize */
  679.  
  680.  
  681.  
  682. /* --------------------------------------------
  683.    Scrolls your text string from right to left.
  684.    -------------------------------------------- */
  685.  
  686. void    ScrollText (Str255    myText, Rect *box)    {
  687.  
  688.         register short        textLen;
  689.         unsigned char        textBuf[256];
  690.         register short        boxWidth;
  691.         Boolean                leftJustify;
  692.         register short        widthSpace, x0, y0;
  693.         register short        bufWidth;
  694.         register short        firstChar, lastChar, charCount;
  695.         long                finalTicks;
  696.         unsigned char        SP = ' ';
  697.  
  698.  
  699.     if ( !isPString((char*)myText) )    CtoPstr((char*)myText);
  700.     
  701.     textLen = *myText;
  702.     if (textLen == 0)    return;                    /* Null string. */
  703.  
  704.     textLen++;                                    /* Include the length byte. */
  705.     BlockMove(myText, textBuf, sizeof(textLen));
  706.     textBuf[0] = textLen;                        /* = textLen+1 from above. */
  707.     textBuf[textLen] = SP;                        /* Add a trailing space. */
  708.  
  709.     widthSpace = CharWidth(SP);
  710.     boxWidth = box->right - box->left;
  711.     if (boxWidth <= widthSpace)    return;
  712.     y0 = box->bottom - box->top;
  713.     if (y0 < 10)    return;                        /* NOT tall enough !! */
  714.     y0 = (y0 - 6) / 2;
  715.     y0 = box->bottom - y0;                        /* y0 = bottom-7 for box.tall = 20 */
  716.  
  717.     firstChar = 1;                                /* Start AFTER length byte. */
  718.     lastChar = 1;
  719.     charCount = 1;
  720.     leftJustify = FALSE;                        /* Assume right-justified. */
  721.  
  722.     /* Shake, Rattle & Scroll, Baby !!! */
  723.     
  724.     while (1)
  725.     {
  726.         bufWidth = TextWidth(textBuf, firstChar, charCount);
  727.         while (bufWidth > boxWidth)
  728.         {
  729.             bufWidth = TextWidth(textBuf, firstChar, charCount);
  730.             firstChar++;            /* Drop first character and */
  731.             charCount--;            /*   try for fit again.     */
  732.         }    /* while (bufWidth > boxWidth) */
  733.  
  734.         /* it Fits */
  735. itFits:
  736.         EraseRect(box);
  737.         x0 = box->right - bufWidth;
  738.         if (x0 <= box->left)    leftJustify = TRUE;    /* Needed ONLY for very */
  739.                                                     /*   short strings.     */
  740.         if (leftJustify)    x0 = box->left;
  741.         /* y0 = box->bottom - 7; */
  742.         MoveTo(x0, y0);
  743.         DrawText(textBuf, firstChar, charCount);
  744.         lastChar++;
  745.  
  746.         if (lastChar > textLen)                        /* We've reached the end. */
  747.         {                
  748.             if (!leftJustify)    {
  749.                 /* short string NOT to left edge yet. */
  750.                 bufWidth += widthSpace;
  751.                 Delay(10, &finalTicks);                /* ... otherwise too quick. */
  752.                 goto itFits;
  753.             }
  754.             else    {                                /* At left edge. */
  755.                 firstChar++;
  756.                 charCount--;
  757.                 if (charCount == 0)    break;            /* All characters moved left. */
  758.             }
  759.         }
  760.         else    charCount++;                        /* Next character. */
  761.         
  762. scrollAgain:
  763.         Delay(10, &finalTicks);                        /* ... otherwise too quick. */
  764.     }    /* while (1) */
  765.     
  766. outtahere:                                            /* Fini!! */
  767.     ValidRect(box);                                    /* No Updates, please ... */
  768.  
  769. }    /* ScrollText */
  770.  
  771.  
  772.  
  773.  
  774. /*    { end file = "scroll.c" }  */
  775.